package com.shinbada.modules.sys.web;

import com.google.common.collect.Lists;
import com.shinbada.common.json.AjaxJson;
import com.shinbada.common.utils.FileUtils;
import com.shinbada.common.utils.StringUtils;
import com.shinbada.config.properties.FileProperties;
import com.shinbada.core.web.BaseController;
import com.shinbada.modules.sys.entity.FileData;
import com.shinbada.modules.sys.utils.FileKit;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.annotations.Param;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import java.util.*;

/**
 * 文件管理Controller
 *
 * @author initcap
 * @version 2018-01-21
 */
@Slf4j
@RestController
@RequestMapping("/sys/file")
@Api(tags = "文件管理")
public class FileController extends BaseController {

    @Autowired
    private FileProperties fileProperties;

    public void init() {
        FileUtils.createDirectory(FileKit.getAttachmentDir());
        FileUtils.createDirectory(FileKit.getMyDocDir());
        FileUtils.createDirectory(FileKit.getShareBaseDir());
    }

    @RequiresPermissions("user")
    @RequestMapping("list")
    @ApiOperation("文件管理列表数据")
    public List<FileData> data() {
        init();
        List<File> targetFiles = Lists.newArrayList();
        targetFiles.add(new File(FileKit.getMyDocDir()));
        targetFiles.add(new File(FileKit.getShareBaseDir()));
        return FileKit.getFileList("files", Lists.newArrayList(targetFiles));
    }

    @RequiresPermissions("user")
    @RequestMapping("move")
    @ApiOperation("移动文件或文件夹")
    public List<Map<String, String>> move(@Param("source") String source, @Param("target") String target) throws IOException {
        List<Map<String, String>> list = Lists.newArrayList();
        target = FileKit.getFileDir(target);
        String[] sourceArra = source.split(",");
        for (String s : sourceArra) {
            s = FileKit.getFileDir(s);
            String fileName = StringUtils.substringAfterLast(s.replace("\\", "/"), "/");
            if (FileUtils.isFolder(s)) {
                File targetFolder = FileUtils.getAvailableFolder(target + "/" + fileName, 0);
                FileUtils.moveDirectory(new File(s), targetFolder);
                Map<String, String> map = new HashMap<>(2);
                map.put("id", FileKit.transDirToUrl(targetFolder.getAbsolutePath()));
                map.put("value", targetFolder.getName());
                list.add(map);
            } else {
                File targetFile = FileUtils.getAvailableFile(target + "/" + fileName, 0);
                FileUtils.moveFile(new File(s), targetFile);
                new File(s).deleteOnExit();
                Map<String, String> map = new HashMap<>(2);
                map.put("id", FileKit.transDirToUrl(targetFile.getAbsolutePath()));
                map.put("value", targetFile.getName());
                list.add(map);
            }

        }
        return list;
    }

    @RequiresPermissions("user")
    @RequestMapping("copy")
    @ApiOperation("copy文件文件夹")
    public List<Map<String, String>> copy(@Param("source") String source, @Param("target") String target) {
        List<Map<String, String>> list = Lists.newArrayList();
        String[] sourceArra = source.split(",");
        for (String s : sourceArra) {
            s = FileKit.getFileDir(s);
            String fileName = StringUtils.substringAfterLast(s.replace("\\", "/"), "/");
            if (FileUtils.isFolder(s)) {
                File targetFolder = FileUtils.getAvailableFolder(target + "/" + fileName, 0);
                if (FileUtils.copyDirectory(s, targetFolder.getAbsolutePath())) {
                    Map<String, String> map = new HashMap<>(2);
                    map.put("id", FileKit.transDirToUrl(targetFolder.getAbsolutePath()));
                    map.put("value", targetFolder.getName());
                    list.add(map);
                }
            } else {
                File targetFile = FileUtils.getAvailableFile(target + "/" + fileName, 0);
                if (FileUtils.copyFile(s, targetFile.getAbsolutePath())) {
                    Map<String, String> map = new HashMap<>(2);
                    map.put("id", FileKit.transDirToUrl(targetFile.getAbsolutePath()));
                    map.put("value", targetFile.getName());
                    list.add(map);
                }
            }

        }

        return list;
    }

    @RequiresPermissions("user")
    @RequestMapping("download")
    @ApiOperation("删除文件管理")
    public void download(@Param("source") String source, HttpServletRequest request, HttpServletResponse response) throws Exception {
        source = FileKit.getFileDir(source);
        File file = new File(source);
        if (!file.exists()) {
            throw new FileNotFoundException("请求的文件不存在");
        }
        OutputStream out = null;
        try {
            response.reset();
            response.setContentType("application/octet-stream; charset=utf-8");
            String agent = request.getHeader("USER-AGENT");
            String fileName = file.getName();
            if (agent != null && agent.indexOf("MSIE") == -1) {
// FF
                String enableFileName = "=?UTF-8?B?" + (new String(Base64.getEncoder().encode(fileName.getBytes("UTF-8")))) + "?=";
                response.setHeader("Content-Disposition", "attachment; filename=" + enableFileName);
            } else {
// IE
                String enableFileName = new String(fileName.getBytes("GBK"), "ISO-8859-1");
                response.setHeader("Content-Disposition", "attachment; filename=" + enableFileName);
            }
            out = response.getOutputStream();
            out.write(FileUtils.readFileToByteArray(file));
            out.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }

    @RequiresPermissions("user")
    @RequestMapping("remove")
    @ApiOperation("删除文件管理")
    public List<Map<String, String>> delete(@Param("source") String source) {
        List<Map<String, String>> list = Lists.newArrayList();
        //先删除文件
        String[] sourceArra = source.split(",");
        for (String s : sourceArra) {
            s = FileKit.getFileDir(s);
            FileUtils.delFile(s);
            Map<String, String> map = new HashMap<>(2);
            map.put("id", FileKit.transDirToUrl(s));
            map.put("value", StringUtils.substringAfterLast(s.replace("\\", "/"), "/"));
            list.add(map);
        }

        return list;
    }

    @RequiresPermissions("user")
    @RequestMapping("createFolder")
    @ApiOperation("创建目录")
    public Map<String, String> create(@Param("source") String source, @Param("target") String target) {
        Map<String, String> map = new HashMap<>(2);
        target = FileKit.getFileDir(target);
        String targetFolderPath = target + "/" + source;
        File targetFolder = FileUtils.getAvailableFolder(targetFolderPath, 0);
        boolean result = FileUtils.createDirectory(targetFolder.getAbsolutePath());
        if (result) {
            map.put("id", FileKit.transDirToUrl(targetFolder.getAbsolutePath()));
            map.put("value", targetFolder.getName());

        }
        return map;
    }

    @RequiresPermissions("user")
    @RequestMapping("rename")
    @ApiOperation("重命名")
    public Map<String, String> rename(@Param("source") String source, @Param("target") String target) {
        Map<String, String> map = new HashMap<>(2);
        source = FileKit.getFileDir(source);
        File sourceFile = new File(source);
        File targetFile = new File(sourceFile.getParent() + "/" + target);
        if (sourceFile.isDirectory()) {
            targetFile = FileUtils.getAvailableFolder(targetFile.getAbsolutePath(), 0);
        } else {
            targetFile = FileUtils.getAvailableFile(targetFile.getAbsolutePath(), 0);
        }
        boolean result = sourceFile.renameTo(targetFile);
        if (result) {
            map.put("id", FileKit.transDirToUrl(targetFile.getAbsolutePath()));
            map.put("value", targetFile.getName());

        }
        return map;
    }

    @RequiresPermissions("user")
    @RequestMapping("upload")
    @ApiOperation("上传文件")
    public Map<String, String> upload(HttpServletRequest request, MultipartFile upload) throws Exception {
        String target = request.getParameter("target");
        String realPath = FileKit.getFileDir(target);
        Map<String, String> map = new HashMap();
        // 判断文件是否为空
        if (!upload.isEmpty()) {
            String name = upload.getOriginalFilename();
            if (fileProperties.isAvailable(name)) {
                // 文件保存路径
                // 转存文件
                FileUtils.createDirectory(realPath);
                String filePath = realPath + "/" + name;
                File newFile = FileUtils.getAvailableFile(filePath, 0);
                upload.transferTo(newFile);
                map.put("id", FileKit.transDirToUrl(newFile.getAbsolutePath()));
                map.put("value", newFile.getName());
                map.put("type", FileKit.getFileType(newFile.getName()));
            } else {
                map.put("id", "");
                map.put("value", "");
                map.put("type", "");
                log.info("【文件管理】非法文件，不允许上传!");
            }
        }
        return map;
    }

    @RequiresPermissions("user")
    @RequestMapping("getUrl")
    @ApiOperation("获取文件网络地址")
    public AjaxJson getUrl(@Param("dir") String dir) throws IllegalStateException {
        return AjaxJson.success().put("url", dir).put("type", FileKit.getFileType(dir));
    }

    @RequiresPermissions("user")
    @RequestMapping("webupload/upload")
    @ApiOperation("下载文件")
    public AjaxJson webupload(HttpServletRequest request, MultipartFile file) throws IllegalStateException, IOException {
        AjaxJson j = new AjaxJson();
        String uploadPath = request.getParameter("uploadPath");
        Calendar cal = Calendar.getInstance();
        int year = cal.get(Calendar.YEAR);
        int month = cal.get(Calendar.MONTH) + 1;
        String fileUrl = FileKit.getAttachmentUrl() + uploadPath + "/" + year + "/" + month + "/";
        String fileDir = FileKit.getAttachmentDir() + uploadPath + "/" + year + "/" + month + "/";
        // 判断文件是否为空
        if (!file.isEmpty()) {
            String name = file.getOriginalFilename();
            if (fileProperties.isAvailable(name)) {
                // 文件保存路径
                // 转存文件
                FileUtils.createDirectory(fileDir);
                String filePath = fileDir + name;
                File newFile = FileUtils.getAvailableFile(filePath, 0);
                file.transferTo(newFile);
                j.put("id", FileKit.transDirToUrl(newFile.getAbsolutePath()));
                j.put("url", fileUrl + newFile.getName());
                return j;
            } else {
                return AjaxJson.error("请勿上传非法文件!");
            }
        } else {
            return AjaxJson.error("文件不存在!");
        }
    }

    @RequiresPermissions("user")
    @RequestMapping("webupload/delete")
    @ApiOperation("批量删除文件管理 按绝对地址")
    public AjaxJson delFile(String id) {
        id = FileKit.getFileDir(id);
        if (FileUtils.delFile(id)) {
            return AjaxJson.success("删除文件成功");
        } else {
            return AjaxJson.error("删除文件失败");
        }
    }

    @RequiresPermissions("user")
    @RequestMapping("webupload/deleteByUrl")
    @ApiOperation("批量删除文件管理 按url")
    public AjaxJson delFileByUrl(String url) {
        String id = FileKit.getFileDir(url);
        if (FileUtils.delFile(id)) {
            return AjaxJson.success("删除文件成功");
        } else {
            return AjaxJson.error("删除文件失败");
        }
    }

}
